Skip to content
New issue

Have a question about this project? Sign up for a free GitHub account to open an issue and contact its maintainers and the community.

By clicking “Sign up for GitHub”, you agree to our terms of service and privacy statement. We’ll occasionally send you account related emails.

Already on GitHub? Sign in to your account

feat(in-app-messaging): add BannerMessage UI component #9124

Conversation

calebpollman
Copy link
Member

Description of changes

Add In-App Messaging BannerMessage React Native UI component for rendering InAppMessage payloads created in the Amazon Pinpoint console:

Example Top Banner

with square image, header, some payload style

top_banner

with square image and primaryButton

image_button

iOS screen shot only
with square image, header, some payload style (container backgroundColor and message text color) and override style (close icon color, message fontSize)

image

Example Middle Banner

with landscape image, header, primaryButton

middle_banner

Example Bottom Banner

with header, primaryButton, secondaryButton, some payload style

bottom_banner

Issue #, if available

NA

Description of how you validated changes

Manually tested in sample app

Checklist

  • PR description included
  • yarn test passes
  • Tests are changed or added
  • Relevant documentation is changed or added (and PR referenced)

By submitting this pull request, I confirm that my contribution is made under the terms of the Apache 2.0 license.

Copy link
Contributor

@elorzafe elorzafe left a comment

Choose a reason for hiding this comment

The reason will be displayed to describe this comment to others. Learn more.

LGTM, just a couple non-blocking questions 🌮


// TODO: delete these once they are no longer needed
// pinpoint max chars 150
export const MAX_MESSAGE =
Copy link
Contributor

Choose a reason for hiding this comment

The reason will be displayed to describe this comment to others. Learn more.

Why MAX_MESSAGE instead of MAX_MESSAGE_LENGTH?

Copy link
Member Author

Choose a reason for hiding this comment

The reason will be displayed to describe this comment to others. Learn more.

No real reason, they are just for my testing

Comment on lines 68 to 70
{primaryButton && (
<View style={styles.buttonsContainer}>
{secondaryButton && (
Copy link
Contributor

Choose a reason for hiding this comment

The reason will be displayed to describe this comment to others. Learn more.

What happen if there is only secondaryButton?

Copy link
Member Author

Choose a reason for hiding this comment

The reason will be displayed to describe this comment to others. Learn more.

Ideally, the contract we have with pinpoint should prevent that from happening, but it seems reasonable to add handling for that scenario


return shouldDelayMessageRendering ? null : (
<MessageWrapper>
<View style={[styles.positionContainer, styles[position]]}>
Copy link
Member

Choose a reason for hiding this comment

The reason will be displayed to describe this comment to others. Learn more.

Nit: This is not blocking but I wonder if styles should be defaultStyle or something? I keep finding myself having to remind myself what the difference between styles and style is. As a reader of foreign code, I would have no idea why they're different things.

Copy link
Member Author

@calebpollman calebpollman Oct 28, 2021

Choose a reason for hiding this comment

The reason will be displayed to describe this comment to others. Learn more.

imo default styling as styles is a pretty standard convention in React Native. That said i do think all the styling applied in these components is not the easiest to parse 😟

Copy link
Member

Choose a reason for hiding this comment

The reason will be displayed to describe this comment to others. Learn more.

default styling as styles is a pretty standard convention in React Native

This is a good point too since static StyleSheets are typically assigned to a styles variable. It was just a thought

buttonText: {
fontSize: BASE_FONT_SIZE,
fontWeight: BASE_FONT_WEIGHT,
lineHeight: getLineHeight(BASE_FONT_SIZE),
Copy link
Member

Choose a reason for hiding this comment

The reason will be displayed to describe this comment to others. Learn more.

Nit: You could extract this to ../constants as well so that it doesn't need to be recalculated if it needs to be used elsewhere.

Comment on lines 25 to 28
export const SMALL_SPACING = 4;
export const BASE_SPACING = 8;
export const LARGE_SPACING = 12;
export const EXTRA_LARGE_SPACING = 16;
Copy link
Member

Choose a reason for hiding this comment

The reason will be displayed to describe this comment to others. Learn more.

Nit: Consider switching this around - i.e. SPACING_X so developers can easily access spacing values rather than typing LARGE and then having to choose spacing vs fontsize etc. This could even be a SPACING object that contains different size properties.

Copy link
Member Author

@calebpollman calebpollman Oct 28, 2021

Choose a reason for hiding this comment

The reason will be displayed to describe this comment to others. Learn more.

Agree with naming, but prefer to keep these explicit exports. Basically feel like putting them in an object implies they should be long lived instead of temporary


import { LINE_HEIGHT_MULTIPLIER } from './constants';

export const getLineHeight = (fontSize: number) => fontSize * LINE_HEIGHT_MULTIPLIER;
Copy link
Member

Choose a reason for hiding this comment

The reason will be displayed to describe this comment to others. Learn more.

Nit: Should this utility be less tied to LINE_HEIGHT_MULTIPLIER i.e. accept multiplier as a parameter? Just a nit question since I don't see any reason why the multiplier would change right now (though it could in theory be configurable in the future)

Copy link
Member Author

Choose a reason for hiding this comment

The reason will be displayed to describe this comment to others. Learn more.

So between facebook/react-native#29507 and my experience with building components in RN feel it is kind of negligent to allow the values of lineHeight to be anything but 1.5 the size of the accompanying fontSize. I'm sure there could still be an argument for allowing it to be configurable, but just wanted to put that out there

useInAppMessaging,
} from '../..';
import { BannerMessageProps, CarouselMessageProps, FullScreenMessageProps } from '../../components';
import { InAppMessageComponents, useInAppMessaging } from '../../context';
Copy link
Member

Choose a reason for hiding this comment

The reason will be displayed to describe this comment to others. Learn more.

Nit: Should useInAppMessaging be in hooks? Isn't it a little unintuitive that this one hook lives elsewhere?

Copy link
Member Author

Choose a reason for hiding this comment

The reason will be displayed to describe this comment to others. Learn more.

I'm kind of leaning towards moving that hooks directory under the components directory since the contents are not going to be public exports, and they have very specific use cases related to the In-App Messaging components. Personally think useInAppMessaging should stay close to the InAppMessagingContext since that is what it exposes, but could be swayed to move it

Copy link
Member

Choose a reason for hiding this comment

The reason will be displayed to describe this comment to others. Learn more.

I feel it would be more intuitive to simply have hooks live together. I know it exposes the context, but it's not really the context itself but rather a helper/wrapper around useContext right?

Comment on lines +4 to +5
close: require('./close.png') as ImageSourcePropType,
warning: require('./warning.png') as ImageSourcePropType,
Copy link
Member

Choose a reason for hiding this comment

The reason will be displayed to describe this comment to others. Learn more.

Nit: Are these assets accounting for high pixel density displays? (They look pretty huge so I'm guessing it's fine)

Copy link
Member

Choose a reason for hiding this comment

The reason will be displayed to describe this comment to others. Learn more.

For my own understanding, are SVG's supported on RN?

Copy link
Member Author

Choose a reason for hiding this comment

The reason will be displayed to describe this comment to others. Learn more.

@reesscot Not out of the box, but with external dependencies yes

Copy link
Member

@cshfang cshfang left a comment

Choose a reason for hiding this comment

The reason will be displayed to describe this comment to others. Learn more.

Lgtm

@codecov-commenter
Copy link

Codecov Report

Merging #9124 (01128d8) into in-app-messaging/main (64a4090) will not change coverage.
The diff coverage is n/a.

Impacted file tree graph

@@                  Coverage Diff                   @@
##           in-app-messaging/main    #9124   +/-   ##
======================================================
  Coverage                  78.00%   78.00%           
======================================================
  Files                        250      250           
  Lines                      18115    18115           
  Branches                    3885     3885           
======================================================
  Hits                       14131    14131           
  Misses                      3854     3854           
  Partials                     130      130           

Continue to review full report at Codecov.

Legend - Click here to learn more
Δ = absolute <relative> (impact), ø = not affected, ? = missing data
Powered by Codecov. Last update 64a4090...01128d8. Read the comment docs.

@calebpollman calebpollman merged commit 8a6bd99 into aws-amplify:in-app-messaging/main Oct 28, 2021
@calebpollman calebpollman deleted the in-app-messaging/add-banner-message branch October 28, 2021 23:15
Copy link
Contributor

@nickarocho nickarocho left a comment

Choose a reason for hiding this comment

The reason will be displayed to describe this comment to others. Learn more.

LGTM! Just a small nit comment for naming conventions.

bottom: ViewStyle;
middle: ViewStyle;
top: ViewStyle;

Copy link
Contributor

Choose a reason for hiding this comment

The reason will be displayed to describe this comment to others. Learn more.

I like the grouping approach you did here :)

Comment on lines +19 to +22
// color
export const BLACK = '#000';
export const LIGHT_GREY = '#e8e8e8';
export const WHITE = '#fff';
Copy link
Contributor

Choose a reason for hiding this comment

The reason will be displayed to describe this comment to others. Learn more.

Nit: I'm not yet familiar with the React Native codebase's patterns, but in the future, it could be good to prefix the color consts with COLOR_ - i.e. COLOR_BLACK, COLOR_WHITE, COLOR_GREY_LIGHT (similar to BANNER_) in order to group the declarations closer together.

@github-actions
Copy link

This pull request has been automatically locked since there hasn't been any recent activity after it was closed. Please open a new issue for related bugs.

Looking for a help forum? We recommend joining the Amplify Community Discord server *-help channels or Discussions for those types of questions.

@github-actions github-actions bot locked as resolved and limited conversation to collaborators Oct 30, 2022
Sign up for free to subscribe to this conversation on GitHub. Already have an account? Sign in.
Labels
None yet
Projects
None yet
Development

Successfully merging this pull request may close these issues.

6 participants